//This code originally came from the Visual Studio SDK for VS2005 and has been customized.
//This code was obtained from the 2006.09 version of the SDK.
//The original version can be found under the name of: C# Example.SyncronousXMLDesigner
/***************************************************************************

Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

***************************************************************************/

using System;
using System.Globalization;

namespace Microsoft.VisualStudio.Shell
{
    /// <summary>
    /// This attribute adds a logical view to the editor created by an editor factory.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public sealed class ProvideXmlViewAttribute : RegistrationAttribute
    {
        private Guid factory;
        private Guid logicalView;
        private string _name = null;
        private string _extension = null;
        private string _namespace = null;
        private bool _matchboth = false;

        /// <summary>
        /// Creates a new RegisterEditorLogicalView attribute to register a logical
        /// view provided by your editor.
        /// </summary>
        /// <param name="factoryType">The type of factory; can be a Type, a GUID or a string representation of a GUID</param>
        /// <param name="logicalViewGuid">The guid of the logical view to register.</param>
        public ProvideXmlViewAttribute(object factoryType, string logicalViewGuid)
        {
            this.logicalView = new Guid(logicalViewGuid);

            // figure out what type of object they passed in and get the GUID from it
            if (factoryType is string)
                this.factory = new Guid((string)factoryType);
            else if (factoryType is Type)
            {
                this.factory = ((Type)factoryType).GUID;
                if (this._name == null)
                    this._name = ((Type)factoryType).Name;
            }
            else if (factoryType is Guid)
                this.factory = (Guid)factoryType;
            else
                throw new ArgumentException("factoryType");

        }

        /// <summary>
        /// Get the Guid representing the type of the editor factory
        /// </summary>
        public Guid FactoryType
        {
            get { return factory; }
        }

        /// <summary>
        /// Get the Guid representing the logical view
        /// </summary>
        public Guid LogicalView
        {
            get { return logicalView; }
        }

        /// <summary>
        /// Get or Set the name of the editor
        /// </summary>
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        /// <summary>
        /// Get or Set the namespace of the XML files that support this view
        /// </summary>
        public string Namespace
        {
            get { return _namespace; }
            set { _namespace = value; }
        }

        /// <summary>
        /// Get or Set the extension of the XML files that support this view
        /// </summary>
        public string Extension
        {
            get { return _extension; }
            set { _extension = value; }
        }

        /// <summary>
        /// Get or Set the whether the XML files that support this view must
        /// match both the file extension and the namespace (Match = "both")
        /// or it is OK to merely match the file extension (Match not specified)
        /// </summary>
        public bool MatchBoth
        {
            get { return _matchboth; }
            set { _matchboth = value; }
        }

        private string XmlViewPath
        {
            get { return string.Format(CultureInfo.InvariantCulture, "XmlDesigners\\{0}", factory.ToString("B")); }
        }


        /// <summary>
        ///     Called to register this attribute with the given context.  The context
        ///     contains the location where the registration inforomation should be placed.
        ///     It also contains other information such as the type being registered and path information.
        /// </summary>
        public override void Register(RegistrationContext context)
        {
            context.Log.WriteLine(String.Format(CultureInfo.CurrentCulture, "XmlDesignerView:  {0}\n", _name));

            using (Key childKey = context.CreateKey(XmlViewPath))
            {
                childKey.SetValue("Editor", factory.ToString("D"));
                childKey.SetValue("LogicalView", logicalView.ToString("D"));

                if (_name == null)
                    _name = string.Empty;
                childKey.SetValue(null, _name);

                if (_namespace != null)
                    childKey.SetValue("Namespace", _namespace);

                if (_extension != null)
                    childKey.SetValue("Extension", _extension);

                if (_matchboth)
                    childKey.SetValue("Match", "both");
            }
        }

        /// <summary>
        /// Unregister this logical view.
        /// </summary>
        /// <param name="context"></param>
        public override void Unregister(RegistrationContext context)
        {
            context.RemoveKey(XmlViewPath);
        }
    }
}
